package com.rgp.servicepay.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.domain.AlipayTradeQueryModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.rgp.internalcommon.dto.ResponseResult;
import com.rgp.internalcommon.response.CheckTradeActionResponse;
import com.rgp.internalcommon.response.FaceToFaceInitialResponse;
import com.rgp.servicepay.constant.AlipayProperties;
import com.rgp.servicepay.feign.ServiceOrderClient;
import com.rgp.servicepay.service.PayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * @author nhp
 * @version 1.0
 * @description TODO
 * @date 2024-04-26 21:51
 */
@Service
public class PayServiceImpl implements PayService {

    @Autowired
    private DefaultAlipayClient alipayClient;

    @Autowired
    private AlipayProperties alipayProperties;

    @Autowired
    private ServiceOrderClient serviceOrderClient;

    @Override
    public ResponseResult faceToFacePay(String orderId, String price, String passengerId) {

        /**
         * 实例化具体API对应的request类，类名称和接口名称对应,
         * 当前调用接口名称：alipay.trade.precreate（统一收单线下交易预创建（扫码支付））
         *
         **/
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();

        /** 设置业务参数  **/
        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();

        /** 商户订单号，商户自定义，需保证在商户端不重复，如：20200612000001 **/
        model.setOutTradeNo(orderId + "");

        /**订单标题 **/
        model.setSubject("RGP滴滴打车");

        /** 订单金额，精确到小数点后两位 **/
        model.setTotalAmount(price);

        /** 订单描述 **/
        model.setBody("id为[" + passengerId + "]的乘客使用RGP滴滴打车服务，打车费用为 + " + price + "元");

        /** 业务扩展参数 **/
        //ExtendParams extendParams = new ExtendParams();

        /** 系统商编号，填写服务商的PID用于获取返佣，返佣参数传值前提：传值账号需要签约返佣协议，用于isv商户。 **/
        //extendParams.setSysServiceProviderId("2088511****07846");

        /** 花呗分期参数传值前提：必须有该接口花呗收款准入条件，且需签约花呗分期 **/
        /** 指定可选期数，只支持3/6/12期，还款期数越长手续费越高 **/
        // extendParams.setHbFqNum("3");

        /** 指定花呗分期手续费承担方式，手续费可以由用户全承担（该值为0），也可以商户全承担（该值为100），但不可以共同承担，即不可取0和100外的其他值。 			**/
        //extendParams.setHbFqSellerPercent("0");

        //model.setExtendParams(extendParams);

        /** 将业务参数传至request中 **/
        request.setBizModel(model);

        /** 异步通知地址，以http或者https开头的，商户外网可以post访问的异步地址，用于接收支付宝返回的支付结果，
         * 如果未收到该通知可参考该文档进行确认：
         * https://opensupport.alipay.com/support/helpcenter/193/201602475759
         * **/
        request.setNotifyUrl(alipayProperties.getNotifyUrl());

        /**第三方调用（服务商模式），传值app_auth_token后，会收款至授权app_auth_token对应商家账号，如何获传值app_auth_token请参考文档：				https://opensupport.alipay.com/support/helpcenter/79/201602494631 **/
        //request.putOtherTextParam("app_auth_token", "传入获取到的app_auth_token值");

        AlipayTradePrecreateResponse response = null;
        try {

            /** 通过alipayClient调用API，获得对应的response类  **/
            response = alipayClient.execute(request);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }

        /** 获取接口调用结果，如果调用失败，可根据返回错误信息到该文档寻找排查方案：
         * https://opensupport.alipay.com/support/helpcenter/101
         **/
        String json = response.getBody();
        System.out.println("json:" + json);

        //解析json数据
        JSONObject jsonObject = JSONObject.parseObject(json);
        //得到alipay_trade_precreate_response数据后再强转JSONObject
        JSONObject jsonobj_two = (JSONObject)jsonObject.get("alipay_trade_precreate_response");
        //再通过jsonobj_two获取到二维码地址
        String qrcode = jsonobj_two.get("qr_code").toString();

        FaceToFaceInitialResponse faceToFaceInitialResponse = new FaceToFaceInitialResponse();
        faceToFaceInitialResponse.setOrderId(orderId);
        faceToFaceInitialResponse.setQrcode(qrcode);

        return ResponseResult.success(faceToFaceInitialResponse);
    }

    @Override
    public ResponseResult checkTradeAction(HttpServletRequest request, HttpServletResponse response) {

        String orderId = request.getParameter("orderId");
        /** 实例化具体API对应的request类，类名称和接口名称对应,当前调用接口名称：alipay.trade.query（统一收单线下交易查询） **/
        AlipayTradeQueryRequest alipayRequest = new AlipayTradeQueryRequest();
        /** 设置业务参数 **/
        AlipayTradeQueryModel model = new AlipayTradeQueryModel();
        model.setOutTradeNo(orderId);

        /** 异步通知/查询接口返回的支付宝交易号，如：2020061622001473951448314322 **/
        //model.setTradeNo("2020061622001473951448314322");

        /** 将业务参数传至request中 **/
        alipayRequest.setBizModel(model);

        /** 第三方调用（服务商模式），必须传值与支付接口相同的app_auth_token **/
        //request.putOtherTextParam("app_auth_token", "传入获取到的app_auth_token值");

        /** 将业务参数传至request中 **/
        alipayRequest.setBizModel(model);

        /** 通过alipayClient调用API，获得对应的response类  **/
        AlipayTradeQueryResponse alipayResponse = null;
        try {
            alipayResponse = alipayClient.execute(alipayRequest);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }

        String json = alipayResponse.getBody();
        System.out.println(json);
        JSONObject jsonObject=JSONObject.parseObject(json);
        JSONObject jsonobj_two=(JSONObject)jsonObject.get("alipay_trade_query_response");
        // 网关返回码,详见文档 https://opendocs.alipay.com/open/common/105806
        String ZFBCode = (String)jsonobj_two.get("code");
        // 业务返回码
        String ZFBSubCode = (String)jsonobj_two.get("sub_code");
        // 业务返回码描述
        String sub_msg=(String)jsonobj_two.get("sub_msg");
        // 交易状态：
        // WAIT_BUYER_PAY（交易创建，等待买家付款）、
        // TRADE_CLOSED（未付款交易超时关闭，或支付完成后全额退款）、
        // TRADE_SUCCESS（交易支付成功）、
        // TRADE_FINISHED（交易结束，不可退款）
        String trade_status=(String)jsonobj_two.get("trade_status");
        CheckTradeActionResponse actionResponse = new CheckTradeActionResponse();
        if (ZFBCode.equals("40004") && ZFBSubCode.equals("ACQ.TRADE_NOT_EXIST")) {
            //订单未创建（用户未扫码）
            actionResponse.setCode(ZFBCode);
            actionResponse.setData("用户未扫码");
        } else if (ZFBCode.equals("10000") && trade_status.equals("WAIT_BUYER_PAY")) {
            //订单已经创建但未支付（用户扫码后但是未支付）
            actionResponse.setCode(ZFBCode);
            actionResponse.setData("non-payment");
        } else if (ZFBCode.equals("10000") && (trade_status.equals("TRADE_SUCCESS") || trade_status.equals("TRADE_FINISHED"))) {
            // 判断ZFBCode是否等于”10000“
            // 并且 trade_status等于TRADE_SUCCESS（交易支付成功）或者 trade_status等于TRADE_FINISHED（交易结束，不可退款）
            //订单已支付（用户扫码完成并且支付成功之后）
            actionResponse.setCode(ZFBCode);
            actionResponse.setData("yes-payment");
        } else {
            actionResponse.setCode(ZFBCode);
            actionResponse.setData(sub_msg);
        }
        return ResponseResult.success(actionResponse);
    }

    @Override
    public void notifyCallback(HttpServletRequest request, HttpServletResponse response) {
        String alipayPublicKey = alipayProperties.getAlipayPublicKey();
        String orderId = request.getParameter("orderId");
        PrintWriter out;
        try {
            out = response.getWriter();
            //获取支付宝POST过来反馈信息
            Map<String, String> params = new HashMap<String, String>();
            Map requestParams = request.getParameterMap();
            //循环遍历支付宝请求过来的参数存入到params中
            for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
                String name = (String) iter.next();
                String[] values = (String[]) requestParams.get(name);
                String valueStr = "";
                for (int i = 0; i < values.length; i++) {
                    valueStr = (i == values.length - 1) ? valueStr + values[i]
                            : valueStr + values[i] + ",";
                }
                //乱码解决，这段代码在出现乱码时使用。
                //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
                params.put(name, valueStr);
            }
            //异步验签：切记alipaypublickey是支付宝的公钥，请去open.alipay.com对应应用下查看。
            boolean flag = false;
            flag = AlipaySignature.rsaCheckV1(params, alipayPublicKey, alipayProperties.getCharset(), alipayProperties.getSignType());
            if (flag) {
                //说明是支付宝调用的本接口
                if (params.get("trade_status").equals("TRADE_SUCCESS") || params.get("trade_status").equals("TRADE_FINISHED")) {
                    System.out.println("收到回调结果，用户已经完成支付");
                    /***
                     * 这里写您的业务逻辑代码,修改订单状态为支付完成
                     */
                    serviceOrderClient.finishOrderPay(orderId);

                    out.write("success");
                }
            } else {
                //验签失败该接口被别人调用
                out.write("支付宝异步回调验签失败，请留意");
            }
            out.flush();
            out.close();
        } catch (IOException ioException) {
            ioException.printStackTrace();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
    }
}
